package 线程通信;

/**
 * 模拟面包店买卖面包：
 * 面包店库存最大上限：100
 * 3个面包师傅，每个师傅每次生产5个，需要一直生产
 * 10个消费者，每个消费者每次消费2个，需要一直消费
 */
public class 面包店 {

    //共享变量：当前库存数
    private static int STORE;

    private static final Object lock = new Object();

    public static void main(String[] args) {
        //面包师傅
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //一直生产
                    while (true){
                        try {
                            //准备生产
                            synchronized (lock){
                                //不满足生产条件
                                while (STORE + 5 > 100){
                                    lock.wait();
                                }
                                //满足生产条件
                                STORE += 5;//生产
                                System.out.printf("%s 生产了5个面包，当前库存：%s\n",
                                        Thread.currentThread().getName(),
                                        STORE);
                                lock.notifyAll();
                                Thread.sleep(1000);//间隔一段时间打印
                            }
                            Thread.sleep(100);//涉及jvm对synchronized优化，暂时不管
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }, "面包师傅["+(i+1)+"]").start();
        }

        //消费者
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //一直消费
                    while (true){
                        try {
                            //准备消费
                            synchronized (lock){
                                //不满足消费条件
                                while (STORE - 2 < 0){
                                    lock.wait();
                                }
                                //满足消费条件
                                STORE -= 2;//消费
                                System.out.printf("%s 消费了2个面包，当前库存：%s\n",
                                        Thread.currentThread().getName(),
                                        STORE);
                                lock.notifyAll();
                                Thread.sleep(1000);//间隔一段时间打印
                            }
                            Thread.sleep(100);//涉及jvm对synchronized优化，暂时不管
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }, "消费者["+(i+1)+"]").start();
        }
    }
}
